home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
strategy
/
xpuzzles.3
/
xpuzzles
/
xpuzzles-5.3.1
/
xcubes
/
xmcubes.c
< prev
Wrap
C/C++ Source or Header
|
1996-02-07
|
15KB
|
520 lines
/*
# MOTIF-BASED CUBES
#
# xmcubes.c
#
###
#
# Copyright (c) 1993 - 96 David Albert Bagley, bagleyd@hertz.njit.edu
#
# All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of the author not be
# used in advertising or publicity pertaining to distribution of the
# software without specific, written prior permission.
#
# This program is distributed in the hope that it will be "useful",
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
*/
/*
Version 5: 95/10/01 Xt/Motif
Version 4: 94/06/07 Xt
Version 3: 93/04/01 Motif
Version 2: 92/12/19 XView
*/
#include <stdlib.h>
#include <stdio.h>
#ifdef VMS
#include <unixlib.h>
#define getlogin cuserid
#else
#ifndef apollo
#include <unistd.h>
#endif
#endif
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/cursorfont.h>
#include <Xm/PanedW.h>
#include <Xm/RowColumn.h>
#include <Xm/Label.h>
#include <Xm/LabelG.h>
#include <Xm/Scale.h>
#include "Cubes.h"
#include "cubes.xbm"
#include "mouse-l.xbm"
#include "mouse-r.xbm"
#ifndef SCOREFILE
#define SCOREFILE "/usr/games/lib/cubes.scores"
#endif
/* The following is in CubesP.h also */
#define MINCUBES 1
#define MAXCUBES 8
#define MAXRECORD 32767
static void Initialize();
static void CallbackCubes();
static void PrintRecord();
static int HandleSolved();
static void ReadRecords();
static void WriteRecords();
static void motif_printf();
static void BlockXSlider();
static void BlockYSlider();
static void BlockZSlider();
static Arg arg[2];
static Widget moves, record, message, cubes, blockX, blockY, blockZ;
static int cubesRecord[MAXCUBES - MINCUBES + 1][MAXCUBES - MINCUBES + 1]
[MAXCUBES - MINCUBES + 1], movesDsp = 0;
static char messageDsp[128] = "Welcome";
static void Usage()
{
(void) fprintf(stderr, "usage: xmcubes\n");
(void) fprintf(stderr,
"\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
(void) fprintf(stderr,
"\t[-display [{host}]:[{vs}]][-fg {color}] [-bg {color}]\n");
(void) fprintf(stderr,
"\t[-brick {color}] [-{border|bd} {color}] [-size{x|y|z} {int}]\n");
exit(1);
}
static XrmOptionDescRec options[] = {
{"-fg", "*cubes.Foreground", XrmoptionSepArg, NULL},
{"-bg", "*Background", XrmoptionSepArg, NULL},
{"-foreground", "*cubes.Foreground", XrmoptionSepArg, NULL},
{"-background", "*Background", XrmoptionSepArg, NULL},
{"-brick", "*cubes.brickColor", XrmoptionSepArg, NULL},
{"-border", "*cubes.brickBorder", XrmoptionSepArg, NULL},
{"-bd", "*cubes.brickBorder", XrmoptionSepArg, NULL},
{"-sizex", "*cubes.sizeX", XrmoptionSepArg, NULL},
{"-sizey", "*cubes.sizeY", XrmoptionSepArg, NULL},
{"-sizez", "*cubes.sizeZ", XrmoptionSepArg, NULL},
};
int main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel;
Widget panel, panel2, rowcol, rowcol2;
Pixmap mouseLeftCursor, mouseRightCursor;
Pixel fg, bg;
toplevel = XtInitialize(argv[0], "Cubes",
options, XtNumber(options), &argc, argv);
if (argc != 1)
Usage();
XtSetArg(arg[0], XtNiconPixmap,
XCreateBitmapFromData(XtDisplay(toplevel),
RootWindowOfScreen(XtScreen(toplevel)),
(char *) cubes_bits, cubes_width, cubes_height));
XtSetArg(arg[1], XmNkeyboardFocusPolicy, XmPOINTER); /* not XmEXPLICIT */
XtSetValues(toplevel, arg, 2);
panel = XtCreateManagedWidget("panel", xmPanedWindowWidgetClass, toplevel,
NULL, 0);
panel2 = XtVaCreateManagedWidget("panel2", xmPanedWindowWidgetClass, panel,
XmNseparatorOn, False,
XmNsashWidth, 1,
XmNsashHeight, 1,
NULL);
rowcol = XtVaCreateManagedWidget("Rowcol", xmRowColumnWidgetClass, panel2,
XmNnumColumns, 2,
XmNorientation, XmHORIZONTAL,
XmNpacking, XmPACK_COLUMN,
NULL);
XtVaGetValues(rowcol, XmNforeground, &fg, XmNbackground, &bg, NULL);
mouseLeftCursor = XCreatePixmapFromBitmapData(XtDisplay(rowcol),
RootWindowOfScreen(XtScreen(rowcol)), mouse_left_bits,
mouse_left_width, mouse_left_height, fg, bg,
DefaultDepthOfScreen(XtScreen(rowcol)));
mouseRightCursor = XCreatePixmapFromBitmapData(XtDisplay(rowcol),
RootWindowOfScreen(XtScreen(rowcol)), mouse_right_bits,
mouse_right_width, mouse_right_height, fg, bg,
DefaultDepthOfScreen(XtScreen(rowcol)));
XtVaCreateManagedWidget("mouseLeftText", xmLabelGadgetClass, rowcol,
XtVaTypedArg, XmNlabelString, XmRString, "Move brick", 11, NULL);
XtVaCreateManagedWidget("mouseLeft", xmLabelGadgetClass, rowcol,
XmNlabelType, XmPIXMAP, XmNlabelPixmap, mouseLeftCursor, NULL);
XtVaCreateManagedWidget("mouseRightText", xmLabelGadgetClass, rowcol,
XtVaTypedArg, XmNlabelString, XmRString, "Randomize", 10, NULL);
XtVaCreateManagedWidget("mouseRight", xmLabelGadgetClass, rowcol,
XmNlabelType, XmPIXMAP, XmNlabelPixmap, mouseRightCursor, NULL);
XtVaCreateManagedWidget("movesText", xmLabelGadgetClass, rowcol,
XtVaTypedArg, XmNlabelString, XmRString, "Moves", 6, NULL);
moves = XtVaCreateManagedWidget("0", xmLabelWidgetClass, rowcol, NULL);
XtVaCreateManagedWidget("recordText", xmLabelGadgetClass, rowcol,
XtVaTypedArg, XmNlabelString, XmRString, "Record", 7, NULL);
record = XtVaCreateManagedWidget("0", xmLabelWidgetClass, rowcol, NULL);
rowcol2 = XtVaCreateManagedWidget("Rowcol2", xmRowColumnWidgetClass, panel2,
NULL);
XtVaGetValues(rowcol2, XmNforeground, &fg, XmNbackground, &bg, NULL);
blockX = XtVaCreateManagedWidget("blockX", xmScaleWidgetClass, rowcol2,
XtVaTypedArg, XmNtitleString, XmRString, "Blocks X", 8,
XmNminimum, MINCUBES,
XmNmaximum, MAXCUBES,
XmNvalue, MINCUBES,
XmNshowValue, True,
XmNorientation, XmHORIZONTAL,
NULL);
XtAddCallback(blockX, XmNvalueChangedCallback, BlockXSlider, NULL);
blockY = XtVaCreateManagedWidget("blockY", xmScaleWidgetClass, rowcol2,
XtVaTypedArg, XmNtitleString, XmRString, "Blocks Y", 8,
XmNminimum, MINCUBES,
XmNmaximum, MAXCUBES,
XmNvalue, MINCUBES,
XmNshowValue, True,
XmNorientation, XmHORIZONTAL,
NULL);
XtAddCallback(blockY, XmNvalueChangedCallback, BlockYSlider, NULL);
blockZ = XtVaCreateManagedWidget("blockZ", xmScaleWidgetClass, rowcol2,
XtVaTypedArg, XmNtitleString, XmRString, "Blocks Z", 8,
XmNminimum, MINCUBES,
XmNmaximum, MAXCUBES,
XmNvalue, MINCUBES,
XmNshowValue, True,
XmNorientation, XmHORIZONTAL,
NULL);
XtAddCallback(blockZ, XmNvalueChangedCallback, BlockZSlider, NULL);
message = XtVaCreateManagedWidget("Play Cubes! (use mouse or keypad)",
xmLabelWidgetClass, rowcol2,
NULL);
cubes = XtCreateManagedWidget("cubes", cubesWidgetClass, panel, NULL,
0);
XtAddCallback(cubes, XtNselectCallback, CallbackCubes, NULL);
Initialize(cubes);
XtRealizeWidget(toplevel);
XGrabButton(XtDisplay(cubes), AnyButton, AnyModifier, XtWindow(cubes),
TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, XtWindow(cubes),
XCreateFontCursor(XtDisplay(cubes), XC_crosshair));
XtMainLoop();
#ifdef VMS
return 1;
#else
return 0;
#endif
}
static void Initialize(w)
Widget w;
{
int sizeX, sizeY, sizeZ;
XtVaSetValues(w,
XtNstart, FALSE,
NULL);
XtVaGetValues(w,
XtNsizeX, &sizeX,
XtNsizeY, &sizeY,
XtNsizeZ, &sizeZ,
NULL);
if (sizeX <= MAXCUBES)
XmScaleSetValue(blockX, sizeX);
if (sizeY <= MAXCUBES)
XmScaleSetValue(blockY, sizeY);
if (sizeZ <= MAXCUBES)
XmScaleSetValue(blockZ, sizeZ);
ReadRecords();
PrintRecord(sizeX, sizeY, sizeZ);
}
static void CallbackCubes(w, clientData, callData)
Widget w;
caddr_t clientData;
cubesCallbackStruct *callData;
{
int sizeX, sizeY, sizeZ;
XtVaGetValues(w,
XtNsizeX, &sizeX,
XtNsizeY, &sizeY,
XtNsizeZ, &sizeZ,
NULL);
(void) strcpy(messageDsp, "");
switch (callData->reason) {
case CUBES_RESTORE:
case CUBES_RESET:
movesDsp = 0;
break;
case CUBES_BLOCKED:
(void) strcpy(messageDsp, "Blocked");
break;
case CUBES_SPACE:
/*(void) strcpy(messageDsp, "Spaces can't move");*/ /* Too annoying */
break;
case CUBES_IGNORE:
(void) strcpy(messageDsp, "Randomize to start");
break;
case CUBES_MOVED:
movesDsp++;
XtSetArg(arg[0], XtNstart, TRUE);
XtSetValues(w, arg, 1);
break;
case CUBES_SOLVED:
if (HandleSolved(movesDsp, sizeX, sizeY, sizeZ))
(void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
else
(void) strcpy(messageDsp, "Solved!");
XtSetArg(arg[0], XtNstart, FALSE);
XtSetValues(w, arg, 1);
break;
case CUBES_RANDOMIZE:
movesDsp = 0;
XtSetArg(arg[0], XtNstart, FALSE);
XtSetValues(w, arg, 1);
break;
case CUBES_DEC_X:
movesDsp = 0;
sizeX--;
PrintRecord(sizeX, sizeY, sizeZ);
XtSetArg(arg[0], XtNsizeX, sizeX);
XtSetValues(w, arg, 1);
if (sizeX <= MAXCUBES)
XmScaleSetValue(blockX, sizeX);
break;
case CUBES_INC_X:
movesDsp = 0;
sizeX++;
PrintRecord(sizeX, sizeY, sizeZ);
XtSetArg(arg[0], XtNsizeX, sizeX);
XtSetValues(w, arg, 1);
if (sizeX <= MAXCUBES)
XmScaleSetValue(blockX, sizeX);
break;
case CUBES_DEC_Y:
movesDsp = 0;
sizeY--;
PrintRecord(sizeX, sizeY, sizeZ);
XtSetArg(arg[0], XtNsizeY, sizeY);
XtSetValues(w, arg, 1);
if (sizeY <= MAXCUBES)
XmScaleSetValue(blockY, sizeY);
break;
case CUBES_INC_Y:
movesDsp = 0;
sizeY++;
PrintRecord(sizeX, sizeY, sizeZ);
XtSetArg(arg[0], XtNsizeY, sizeY);
XtSetValues(w, arg, 1);
if (sizeY <= MAXCUBES)
XmScaleSetValue(blockY, sizeY);
break;
case CUBES_DEC_Z:
movesDsp = 0;
sizeZ--;
PrintRecord(sizeX, sizeY, sizeZ);
XtSetArg(arg[0], XtNsizeZ, sizeZ);
XtSetValues(w, arg, 1);
if (sizeZ <= MAXCUBES)
XmScaleSetValue(blockZ, sizeZ);
break;
case CUBES_INC_Z:
movesDsp = 0;
sizeZ++;
PrintRecord(sizeX, sizeY, sizeZ);
XtSetArg(arg[0], XtNsizeZ, sizeZ);
XtSetValues(w, arg, 1);
if (sizeZ <= MAXCUBES)
XmScaleSetValue(blockZ, sizeZ);
break;
case CUBES_COMPUTED:
XtSetArg(arg[0], XtNstart, FALSE);
XtSetValues(w, arg, 1);
break;
case CUBES_UNDO:
movesDsp--;
XtSetArg(arg[0], XtNstart, TRUE);
XtSetValues(w, arg, 1);
break;
}
motif_printf(message, "%s", messageDsp);
motif_printf(moves, "%d", movesDsp);
}
static void BlockXSlider(w, clientData, cbs)
Widget w;
XtPointer clientData;
XmScaleCallbackStruct *cbs;
{
int sizeX = cbs->value, sizeY, sizeZ, oldX;
XtVaGetValues(cubes,
XtNsizeX, &oldX,
XtNsizeY, &sizeY,
XtNsizeZ, &sizeZ,
NULL);
if (oldX != sizeX) {
XtVaSetValues(cubes,
XtNsizeX, sizeX,
NULL);
movesDsp = 0;
motif_printf(moves, "%d", movesDsp);
PrintRecord(sizeX, sizeY, sizeZ);
}
}
static void BlockYSlider(w, clientData, cbs)
Widget w;
XtPointer clientData;
XmScaleCallbackStruct *cbs;
{
int sizeX, sizeY = cbs->value, sizeZ, oldY;
XtVaGetValues(cubes,
XtNsizeX, &sizeX,
XtNsizeY, &oldY,
XtNsizeZ, &sizeZ,
NULL);
if (oldY != sizeY) {
XtVaSetValues(cubes,
XtNsizeY, sizeY,
NULL);
movesDsp = 0;
motif_printf(moves, "%d", movesDsp);
PrintRecord(sizeX, sizeY, sizeZ);
}
}
static void BlockZSlider(w, clientData, cbs)
Widget w;
XtPointer clientData;
XmScaleCallbackStruct *cbs;
{
int sizeX, sizeY, sizeZ = cbs->value, oldZ;
XtVaGetValues(cubes,
XtNsizeX, &sizeX,
XtNsizeY, &sizeY,
XtNsizeZ, &oldZ,
NULL);
if (oldZ != sizeZ) {
XtVaSetValues(cubes,
XtNsizeZ, sizeZ,
NULL);
movesDsp = 0;
motif_printf(moves, "%d", movesDsp);
PrintRecord(sizeX, sizeY, sizeZ);
}
}
static void PrintRecord(sizeX, sizeY, sizeZ)
int sizeX, sizeY, sizeZ;
{
int i = sizeX - MINCUBES, j = sizeY - MINCUBES, k = sizeZ - MINCUBES;
if (sizeX > MAXCUBES || sizeY > MAXCUBES || sizeZ > MAXCUBES)
motif_printf(record, "NOT RECORDED");
else if (cubesRecord[i][j][k] >= MAXRECORD)
motif_printf(record, "NEVER");
else
motif_printf(record, "%d", cubesRecord[i][j][k]);
}
static int HandleSolved(counter, sizeX, sizeY, sizeZ)
int counter, sizeX, sizeY, sizeZ;
{
int i = sizeX - MINCUBES, j = sizeY - MINCUBES, k = sizeZ - MINCUBES;
if (sizeX <= MAXCUBES && sizeY <= MAXCUBES && sizeZ <= MAXCUBES &&
counter < cubesRecord[i][j][k]) {
cubesRecord[i][j][k] = cubesRecord[i][k][j] = cubesRecord[j][i][k] =
cubesRecord[j][k][i] = cubesRecord[k][i][j] = cubesRecord[k][j][i] =
counter;
WriteRecords();
PrintRecord(sizeX, sizeY, sizeZ);
return TRUE;
}
return FALSE;
}
static void ReadRecords()
{
FILE *fp;
int i, j, k, n;
for (i = 0; i < MAXCUBES - MINCUBES + 1; i++)
for (j = i; j < MAXCUBES - MINCUBES + 1; j++)
for (k = j; k < MAXCUBES - MINCUBES + 1; k++)
cubesRecord[k][j][i] = cubesRecord[k][i][j] =
cubesRecord[j][k][i] = cubesRecord[j][i][k] =
cubesRecord[i][k][j] = cubesRecord[i][j][k] = MAXRECORD;
if ((fp = fopen(SCOREFILE, "r")) == NULL)
motif_printf(message, "Can not open %s, taking defaults.\n", SCOREFILE);
else {
for (i = 0; i < MAXCUBES - MINCUBES + 1; i++)
for (j = i; j < MAXCUBES - MINCUBES + 1; j++)
for (k = j; k < MAXCUBES - MINCUBES + 1; k++) {
(void) fscanf(fp, "%d", &n);
cubesRecord[k][j][i] = cubesRecord[k][i][j] =
cubesRecord[j][k][i] = cubesRecord[j][i][k] =
cubesRecord[i][k][j] = cubesRecord[i][j][k] = n;
}
(void) fclose(fp);
}
}
static void WriteRecords()
{
FILE *fp;
int i, j, k;
if ((fp = fopen(SCOREFILE, "w")) == NULL)
motif_printf(message, "Can not write to %s.\n", SCOREFILE);
else {
for (i = 0; i < MAXCUBES - MINCUBES + 1; i++) {
for (j = i; j < MAXCUBES - MINCUBES + 1; j++) {
for (k = j; k < MAXCUBES - MINCUBES + 1; k++)
(void) fprintf(fp, "%d ", cubesRecord[i][j][k]);
(void) fprintf(fp, "\n");
}
(void) fprintf(fp, "\n");
}
(void) fclose(fp);
}
}
#include <varargs.h>
static void motif_printf(va_alist)
va_dcl
{
Widget w;
char *format;
va_list args;
char str[1000];
Arg wargs[10];
XmString xmstr;
va_start(args);
w = va_arg(args, Widget);
if (!XtIsSubclass(w, xmLabelWidgetClass))
XtError("motif_printf() requires a Label Widget");
format = va_arg(args, char *);
(void) vsprintf(str, format, args);
xmstr = XmStringCreateLtoR(str, XmSTRING_DEFAULT_CHARSET);
XtSetArg(wargs[0], XmNlabelString, xmstr);
XtSetValues(w, wargs, 1);
va_end(args);
}